package com.cans.lightning.business.system.service.impl;

import com.cans.lightning.base.mapper.IBaseMapper;
import com.cans.lightning.base.service.impl.BaseServiceImpl;
import com.cans.lightning.business.pms.entity.SysUser;
import com.cans.lightning.business.pms.service.api.ISysUserService;
import com.cans.lightning.business.system.dao.FileInfoDao;
import com.cans.lightning.business.system.dto.FileInfoDto;
import com.cans.lightning.business.system.entity.FileInfo;
import com.cans.lightning.business.system.enums.StorageTypeEnum;
import com.cans.lightning.business.system.handler.api.PictureViewHandler;
import com.cans.lightning.business.system.mapper.FileInfoMapperI;
import com.cans.lightning.business.system.service.api.IFileInfoService;
import com.cans.lightning.config.system.SystemSetting;
import com.cans.lightning.utils.system.PathUtil;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.beetl.sql.mapper.BaseMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;

/**
 * 文件服务
 *
 * @author shencan
 * @date 2020/6/14 20:53
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class FileInfoServiceImpl extends BaseServiceImpl<FileInfo, FileInfoDto, String> implements IFileInfoService {

    private static final Logger logger = LoggerFactory.getLogger(FileInfoServiceImpl.class);

    @Resource
    private FileInfoDao fileInfoDao;
    @Resource
    private FileInfoMapperI fileInfoMapper;
    @Resource
    private ISysUserService sysUserService;
    @Resource
    private SystemSetting systemConfig;
    @Resource
    private ApplicationContext applicationContext;

    private final Map<String, PictureViewHandler> pictureViewHandlerMap = Maps.newHashMap();

    @PostConstruct
    public void afterPropertiesSet() {
        Map<String, PictureViewHandler> beansOfType = applicationContext.getBeansOfType(PictureViewHandler.class);
        logger.debug(">>>>>>>>>>>>>>>方法初始化");
        beansOfType.forEach((k, v) -> {
            pictureViewHandlerMap.put(v.type(), v);
            logger.error("注入 :" + v.type());
        });


    }

    @Override
    public BaseMapper<FileInfo> getDaoImpl() {
        return fileInfoDao;
    }

    @Override
    public IBaseMapper<FileInfo, FileInfoDto, String> getMapperImpl() {
        return fileInfoMapper;
    }

    @Override
    public void saveOrUpdate(FileInfo fileInfo) {
        SysUser currentUser = sysUserService.getCurrentUser();
        fileInfo.setUsername(currentUser.getUsername());
        super.saveOrUpdate(fileInfo);
    }

    @Override
    public FileInfo upload(MultipartFile multipartFile) throws IOException {

        String fileName = multipartFile.getOriginalFilename();
        assert fileName != null;
        String fileType = getFileType(fileName);

        FileInfo fileInfo = new FileInfo();

        String basePath = systemConfig.getBasePath() + PathUtil.getBasePath();

        fileInfo.setFileName(fileName);
        fileInfo.setFileType(fileType);
        fileInfo.setUsername(sysUserService.getCurrentUser().getUsername());
        fileInfo.setStorageType(systemConfig.getStorageType());
        this.saveOrUpdate(fileInfo);

        switch (StorageTypeEnum.valueOf(systemConfig.getStorageType())) {

            case DEFAULT:
                // 将文件保存在服务器上

                String filePath = basePath + "/" + fileInfo.getId() + "." + fileType;
                fileInfo.setFilePath(filePath);
                File dest = new File(filePath);
                boolean mkdirs = dest.mkdirs();
                multipartFile.transferTo(dest);
                break;
            case MONGODB:
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + systemConfig.getStorageType());
        }

        return fileInfo;

    }

    @Override
    public void view(OutputStream outputStream, String fileId) throws IOException {

        FileInfo fileInfo = this.getById(fileId);
        PictureViewHandler pictureViewHandler = pictureViewHandlerMap.get(fileInfo.getStorageType());
        if (pictureViewHandler != null) {
            pictureViewHandler.view(outputStream, fileInfo);
        }

    }


    String getFileType(String fileName) {
        int startIndex = fileName.lastIndexOf(".");
        if (startIndex != -1) {
            return fileName.substring(startIndex + 1).toLowerCase();
        } else {
            return "";
        }
    }

}
